﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;
using net.veekee.common;
using System.Text.RegularExpressions;
using net.veekee.common.rules;
using net.veekee.common.data;
using PcapDotNet.Core;
using PcapDotNet.Packets;
using net.veekee.logprocessor.plugin.input;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Http;

namespace net.veekee.logprocessor.plugin.wireshark
{
    public class PCAPProcessor : AProcessor<PCAPEntry>
    {
        //private static Queue<IpV4Datagram> requestQueue = new Queue<IpV4Datagram>(30); 

        private ulong processed = 0;
        private ulong validated = 0;
        private String filename = "";

        protected override bool ProcessFile(String _filename)
        {
            try
            {
                this.filename = _filename;
                PcapDotNet.Analysis.PcapDotNetAnalysis.OptIn = false;

                OfflinePacketDevice selectedDevice = new OfflinePacketDevice(filename);

                using (PacketCommunicator communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))
                {
                    if (Options.GetInstance().Get("input.wireshark.pattern").Length > 0)
                    {
                        using (BerkeleyPacketFilter filter = communicator.CreateFilter(Options.GetInstance().Get("input.wireshark.pattern")))
                        {
                            communicator.SetFilter(filter);
                        }
                    }
                    communicator.ReceivePackets(0, this.DispatcherHandler);
                }
                Log.GetInstance().Debug("Statistics : {0} processed / {1} validated", this.processed, this.validated);
                return true;
            }
            catch (Exception e)
            {
                Log.GetInstance().Debug(e.ToString());
            }
            finally
            {
                Log.GetInstance().WriteProgressBarEnd();
            }
            return false;
        }

        private void DispatcherHandler(Packet packet)
        {
            // http://pcapdotnet.codeplex.com/discussions/245743 ?
            try
            {
                PCAPEntry entry = new PCAPEntry();
                entry.Packet = packet;
                this.stats_read++;
                entry.Line = this.stats_read;
                entry.Filename = this.filename;
                entry.Fields.Set<DateTime>("Timestamp", entry.Packet.Timestamp);

                this.OnNewItem(entry);
            }
            catch (Exception ex)
            {
                Log.GetInstance().Error("Error: {0}", ex.Message);
            }
        }
    }
}
